/* 
 * File:   xmlreader.h
 * Author: ben
 *
 * Created on March 15, 2009, 5:35 PM
 */

#ifndef _XMLREADER_H
#define	_XMLREADER_H


#include "xmlParser.h"
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <vector>


using namespace std;

class Coeff{
public:
    string method;
    //string type;
    double coefficient;
};

class Ncoeff{
public:

    Ncoeff(){
    };
    Ncoeff(int nmethods,int nnodes){
        Setup(nmethods,nnodes);
    }
    ~Ncoeff(){
        thiscoeff.clear();
        thisnames.clear();
        thismethods.clear();
        thisw.clear();
    }
    void Setup(int nmethods,int nnodes){
        int i;
        thisn   =   nnodes;
        thisnm  =   nmethods;
        thisw.resize(thisnm);
        thiscoeff.resize(thisn*thisn*thisnm);
        //cout << "size>>" << thiscoeff.size() << endl;
        for(i=0;i<thiscoeff.size();i++){
            thiscoeff[i].coefficient=0;
        }
        return;
    }
    int getNm(){
        return(thismethods.size());
    }
    int getN(){
        return(thisn);
    }
    void addInfo(string inmethod,string coeff, string infrom,string into){

        putCoeff(NameToInt(infrom),NameToInt(into),MethodToInt(inmethod),atof(coeff.data()));
    }
    int NameToInt(string input){
        int i;
        string *temp;
        temp    =new string;
        *temp   =input;
        //cout << "NameToInt:" << input << endl;
        for(i=0;i<thisnames.size();i++){
            if(thisnames[i]==input){
                return(i);
            }
        }
        thisnames.push_back(*temp);
        return(thisnames.size()-1);
    }
    void putCoeff(int i, int j,int k,double input){
        int pos;
        pos =   k*thisn*thisn+i*thisn+j;
        //cout << "pos:" << pos << endl;
        //cout << thismethods[k] << endl;
        thiscoeff[pos].coefficient  =input;
        thiscoeff[pos].method       =thismethods[k];
    }
    double getCoeff(int i,int j,int k){
        return(thiscoeff[k*thisn*thisn+i*thisn+j].coefficient);
    }
    int MethodToInt(string input){
        int i;
        string *temp;
        temp=new string;
        *temp=input;
        //cout << "input meth2int:" << input << endl;
        for(i=0;i<thismethods.size();i++){
            if(thismethods[i]==input){
                return(i);
            }
        }
        thismethods.push_back(*temp);
        return(thismethods.size()-1);
    }
    int CheckIntegrity(){
        cout << "================" << endl;
        cout << "Integrity check:" << endl;
        cout << "================" << endl;
        cout << "Number of nodes (actual):" << thisnames.size() << endl;
        cout << "Number of nodes (anonced):" << thisn << endl;
        cout << "Number of methods (actual):" << thismethods.size() << endl;
        cout << "Number of nodes (anonced):" << thisnm << endl;
        cout << "================" << endl;
    }
    void putWeight(string method,string inw){
        thisw[MethodToInt(method)]  =   atof(inw.data());

    }
    double getWeight(int i){
        if(i<thisw.size()){
            return(thisw[i]);
        }
        return(-1);
    }
    int setWeight(int i, double val){
        if(i<thisw.size()){
            thisw[i]=val;
        }
        return(-1);
    }
    double getWeight(string method){
        return(thisw[MethodToInt(method)]);
    }
    string getName(int i){
        if(i<thisnames.size()){
            return(thisnames[i]);
        }
        return("notFOUND");
    }
private:
    int thisn;
    int thisnm;
    vector<Coeff> thiscoeff;
    vector<string> thisnames;
    vector<string> thismethods;
    vector<double> thisw;
};


class XmlReader {
public:
    double getVal(int i, int j,int method){
        return(MyCoeff->getCoeff(i,j,method));
    }
    string getName(int i){
        return(MyCoeff->getName(i));
    }
    int getNm(){
        return(MyCoeff->getNm());
    }
    double GetPonderatedEdge(int ifrom,int ito);
    XmlReader(string pathname,string fname);
    //XmlReader(const XmlReader& orig);
    int getSize(){
        return(MyCoeff->getN());
    }
    ~XmlReader();
    int ReadWeights(string fname);
    int ReloadWeights();
    int NormaliseWeights();
    int setWeight(int i, double val){
        MyCoeff->setWeight(i,val);
    };
    double getWeight(int i){
        return(MyCoeff->getWeight(i));
    };
    int PutInfile(string fname);
private:
    XMLNode xMainNode;
    string thisname;
    string thispath;
    string thisname_w;
    Ncoeff *MyCoeff;
};


#endif	/* _XMLREADER_H */

